// Copyright (c) 2008 Matthew Johnson
// Licensed under the MIT License (see license.txt)
package actionml.animation {
	import actionml.Global;
	
	import flash.filters.BitmapFilter;
	class FilterProxyRenderer extends RendererBase implements IProxyRenderer {
		private var _renderer:IRendererInternal;
		private var _proxyName:String;
		private var _filterClass:Class;
		public static function isApplicable(proxyName:String):Boolean {
			return Class["forName"](proxyName) != null;
		}
		public static function getProxyTargetClass(proxyName:String):Class {
			return Class["forName"](proxyName);
		}
		public function FilterProxyRenderer(target:Object, proxyName:String, renderer:IRendererInternal) {
			var t:Object = FilterProxyRenderer["getTracer"]({method:"FilterProxyRenderer", context: "arg"});
			if (!target || !proxyName || !renderer) {
				t.warn("An expected argument was not provided." +
					"  The values were target:", target, ", proxyName:", proxyName, ", renderer:", renderer);
			}
			_renderer = renderer;
			_target = target;
			_proxyName = proxyName;
			_filterClass = Class["forName"](proxyName);
			if (!_filterClass) {
				t.warn("A filter class was not found that corresponds with", proxyName, ".");
			}
			renderer.addEventListener(RenderEvent.COMPLETE_RENDERING, this.rendererEvent, false, 0, true);
		}
		public override function get name():String {
			return _proxyName + "." + _renderer.name;
		}
		public function get renderer():IRenderer {
			return _renderer;
		}
		public override function get rendering():Boolean {
			return _renderer.rendering;
		}
		public override function prepareToRender() {
			super.prepareToRender();
			var filters:Array = _target.filters;
			_renderer.setTarget(findFilter(filters));
			if (!_renderer.target) {
				_renderer.setTarget(new _filterClass());
				filters = _target.filters.append(_renderer.target);
			} 
			_renderer.prepareToRender();
			_target.filters = filters;
		}
		public override function stopRendering() {
			super.stopRendering();
			_renderer.stopRendering();
		}
		public override function interrupted(interruptedBy:IRenderer) {
			super.interrupted(interruptedBy);
			_renderer.interrupted(IProxyRenderer(interruptedBy).renderer);
		}
		public override function render(rc:RenderContext) {
			if (!("fprFilters" in rc)) {
				rc["fprFilters"] = _target.filters; // fpr is a prefix to avoid name conflicts on the context
				rc.addTargetPostRenderFunction(FilterProxyRenderer.targetPostRender);
			}
			_renderer.setTarget(findFilter(rc["fprFilters"]));
			_renderer.render(rc);
		}
		private function rendererEvent(e:RenderEvent) {
			this.sendEvent(new RenderEvent(e.type, e.otherRenderer));
		}
		private function findFilter(filters:Array) {
			for each (var f:BitmapFilter in filters) {
				if (f["constructor"] == _filterClass) {
					return f;
				}
			}
			return null;
		}
		private static function targetPostRender(o:Object, rc:RenderContext) {
			o.filters = rc["fprFilters"];
			delete rc["fprFilters"];
		}
	}
}